/*
 * ParticleObject.h
 *
 *  Created on: 2009/03/03
 *      Author: Yongshik Cho
 */

#ifndef PARTICLEOBJECT_H_
#define PARTICLEOBJECT_H_

#include "RenderObject.h"


class Particle
{
public:
	friend class ParticleObject;

public:
	Particle() {}
	virtual ~Particle() {}

public:
	inline const Vector2D& getPosition() const { return mPosition; }
	inline void setPosition(const Vector2D& pos) { mPosition = pos; }
	inline const Vector2D& getDirection() const { return mDirection; }
	inline void setDirection(const Vector2D& dir) { mDirection = dir; }
	inline const float getRadialAccel() const { return mRadialAccel; }
	inline void setRadialAccel(const float ra) { mRadialAccel = ra; }
	inline const float getTangentialAccel() const { return mTangentialAccel; }
	inline void setTangentialAccel(const float ta) { mTangentialAccel = ta; }
	inline const Color& getColor() const { return mColor; }
	inline void setColor(const Color& color) { mColor = color; }
	inline const Color& getDeltaColor() { return mDeltaColor; }
	inline void setDeltaColor(const Color& color) { mDeltaColor = color; }
	inline const float getSize() const { return mSize; }
	inline void setSize(const float size) { mSize = size; }
	inline const float getLife() const { return mLife; }
	inline void setLife(const float life) { mLife = life; }

protected:
	Vector2D	mPosition;
	Vector2D	mDirection;

	float		mRadialAccel;
	float		mTangentialAccel;
	float		mSize;
	float		mLife;

	Color		mColor;
	Color		mDeltaColor;
};

class ParticleObject : public RenderObject
{
public:
	ParticleObject();
	virtual ~ParticleObject();

public:
	void addParticle(Particle* particle);
	Particle* newParticle();

	inline const uint32 getParticleCount() const { return (uint32)mParticles.size(); }
	Particle* getParticle(const uint32 index);

	inline const uint32 getTotalParticles() const { return mTotalParticles; }
	inline void setTotalParticles(const uint32 ui) { mTotalParticles = ui; }

	inline const float getDuration() const { return mDuration; }
	inline void setDuration(const float f) { mDuration = f; }
	inline const float getAngle() const { return mAngle; }
	inline void setAngle(const float f) { mAngle = f; }
	inline const float getAngleVariance() const { return mAngleVariance; }
	inline void setAngleVariance(const float f) { mAngleVariance = f; }
	inline const float getSpeed() const { return mSpeed; }
	inline void setSpeed(const float f) { mSpeed = f; }
	inline const float getSpeedVariance() const { return mSpeedVariance; }
	inline void setSpeedVariance(const float f) { mSpeedVariance = f; }
	inline const float getTangentialAccel() const { return mTangentialAccel; }
	inline void setTangentialAccel(const float f) { mTangentialAccel = f; }
	inline const float getTangentialAccelVariance() const { return mTangentialAccelVariance; }
	inline void setTangentialAccelVariance(const float f) { mTangentialAccelVariance = f; }
	inline const float getRadialAccel() const { return mRadialAccel; }
	inline void setRadialAccel(const float f) { mRadialAccel = f; }
	inline const float getRadialAccelVariance() const { return mRadialAccelVariance; }
	inline void setRadialAccelVariance(const float f) { mRadialAccelVariance = f; }
	inline const float getSize() const { return mSize; }
	inline void setSize(const float f) { mSize = f; }
	inline const float getSizeVariance() const { return mSizeVariance; }
	inline void setSizeVariance(const float f) { mSizeVariance = f; }
	inline const float getLife() const { return mLife; }
	inline void setLife(const float f) { mLife = f; }
	inline const float getLifeVariance() const { return mLifeVariance; }
	inline void setLifeVariance(const float f) { mLifeVariance = f; }
	inline const float getEmissionRate() const { return mEmissionRate; }
	inline void setEmissionRate(const float f) { mEmissionRate = f; }

	inline const Color& getStartColor() const { return mStartColor; }
	inline void setStartColor(const Color& c) { mStartColor = c; }
	inline const Color& getStartColorVariance() const { return mStartColorVariance; }
	inline void setStartColorVariance(const Color& c) { mStartColorVariance = c; }
	inline const Color& getEndColor() const { return mEndColor; }
	inline void setEndColor(const Color& c) { mEndColor = c; }
	inline const Color& getEndColorVariance() const { return mEndColorVariance; }
	inline void setEndColorVariance(const Color& c) { mEndColorVariance = c; }

	inline const Vector2D& getGravity() const { return mGravity; }
	inline void setGravity(const Vector2D& v) { mGravity = v; }
	inline const Vector2D& getSource() const { return mSource; }
	inline void setSource(const Vector2D& v) { mSource = v; }
	inline const Vector2D& getPositionVariance() const { return mPositionVariance; }
	inline void setPositionVariance(const Vector2D& v) { mPositionVariance = v; }

	inline const bool getBlendAdditive() const { return mBlendAdditive; }
	inline void setBlendAdditive(const bool ba) { mBlendAdditive = ba; }
	inline const bool getColorModulate() const { return mColorModulate; }
	inline void setColorModulate(const bool cm) { mColorModulate = cm; }

public:
	virtual void tick(const uint32 elapsed);
	virtual void reset();

private:
	float		mDuration;
	float		mElapsed;
	float		mAngle;
	float		mAngleVariance;
	float		mSpeed;
	float		mSpeedVariance;
	float		mTangentialAccel;
	float		mTangentialAccelVariance;
	float		mRadialAccel;
	float		mRadialAccelVariance;
	float		mSize;
	float		mSizeVariance;
	float		mLife;
	float		mLifeVariance;
	float		mEmissionRate;
	float		mEmitCounter;

	Vector2D	mGravity;
	Vector2D	mSource;
	Vector2D	mPositionVariance;

	Color		mStartColor;
	Color		mStartColorVariance;
	Color		mEndColor;
	Color		mEndColorVariance;

	uint32		mTotalParticles;

	bool		mBlendAdditive;
	bool		mColorModulate;

	vector<Particle*>	mParticles;
};

#endif /* PARTICLEOBJECT_H_ */
